package Model;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Observable;
import java.util.Timer;
import java.util.concurrent.TimeUnit;

import javax.swing.DefaultListModel;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;

import View.PlayerView;
import datalayer.DBOpath;
import datalayer.DBobject;

public class PlayerModel extends Observable implements ActionListener{

	private static PlayerModel instance;
	DefaultListModel<String> model = PlayerView.modelSongs;
	private boolean play = false;
	private Timer timer = new Timer();
	private Thread t;
	private String mapPath = null;
	private Component parent;
	private boolean pause = false;
	ArrayList<Nummer> songs = new ArrayList<Nummer>();

	private boolean isRunning;
	private javax.swing.Timer secondstimer = new javax.swing.Timer(100, this);
	private long startTime;
	private long pauseTime;


	public static PlayerModel getInstance() {
		if (instance == null) {
			instance = new PlayerModel();
		}
		return instance;
	}

	private PlayerModel() {
		PlayerView.sldTimeLine.setValue(0);
		setVolume();


//		try {
//			URL url = new URL("http://www.google.nl");
//
//			for(int i = 0; i <= 5; i++){
//				Connect.openWebpage(url);
//			}
//			
//		} catch (MalformedURLException e) {
//			
//			e.printStackTrace();
//		}

	}

	//When btnPlay is pressed. 
	@SuppressWarnings("deprecation")
	public void playPause(){
		play = !play;


		if(!play){
			View.PlayerView.btnPlay.setText(">");
			t.suspend();
			pause = true;
			pauseCountUpTimer();
			PlayerView.visual.stop();
		}else{
			View.PlayerView.btnPlay.setText("||");
			if(pause){
				t.resume();
				pause = false;
				startCountUpTimer();
				PlayerView.visual.start();

			}else{
				play();
			}
		}
	}

	public void listSelectionChanged(){
		//		stop();
		//		pause = false;
		//		play = false;
		//		View.PlayerView.btnPlay.setText(">");
	}

	public void doubleClick(){
		stop();
		resetCountUpTimer();
		play = true;
		pause = false;
		View.PlayerView.btnPlay.setText("||");
		play();
	}

	public boolean isPause() {
		return pause;
	}

	public void search(String input){

		input = input.toLowerCase();

		for(int i = 0; i < PlayerView.lstSongs.getModel().getSize();i++){
			String song = PlayerView.lstSongs.getModel().getElementAt(i).toLowerCase();

			if(song.contains(input)){
				PlayerView.lstSongs.setSelectedIndex(i);
				PlayerView.lstSongs.ensureIndexIsVisible(i);
				PlayerView.lstSongs.getNextMatch(input, i, null);
			}
		}
	}

	public void browse(){
		
//		DBOpath p = new DBOpath();
		
		JFileChooser chooser = new JFileChooser(mapPath);
	

		chooser.setMultiSelectionEnabled(true);
		FileNameExtensionFilter filter = new FileNameExtensionFilter("MP3", "mp3");
		chooser.setFileFilter(filter);
		
		int returnVal = chooser.showOpenDialog(parent);
		if(returnVal == JFileChooser.APPROVE_OPTION) {

			File[] files = chooser.getSelectedFiles();

			mapPath = chooser.getSelectedFile().getAbsolutePath();
			System.err.println(mapPath);
			
//			p.save(mapPath);
			

			for(int i=0; i < files.length; i++ ){

				String path = files[i].getAbsolutePath();

				path = path.replaceAll("\\\\","/");

				System.out.println(path);
				DBobject db = new DBobject();

				Nummer s = new Nummer("file:///" + path);			

				boolean dupe = false;

				for(int j = 0; j < songs.size(); j++){
					if(songs.get(j).getNaam().equalsIgnoreCase(s.getNaam())){
						dupe = true;
					}
				}

				if(!dupe){
					db.saveDB(s); 
					addToListModel(s);
				}else{
					int dialogButton = JOptionPane.YES_NO_OPTION;
					int dialogResult = JOptionPane.showConfirmDialog (null, s.getNaam() + " already exists. Would you like to add it anyway?","Warning",dialogButton);

					if(dialogResult == JOptionPane.YES_OPTION){
						db.saveDB(s);
						addToListModel(s);
					}
				}
			}
		}
	}

	public void play(){
		try {
			DBobject db = new DBobject();
			ArrayList<Nummer> songs = new ArrayList<Nummer>();
			songs = db.loadDB();

			String selectedSong = songs.get(PlayerView.lstSongs.getSelectedIndex()).getLocatie();
			PlayerThread.path = selectedSong;
			t = new Thread(PlayerThread.getInstance());

			t.start();

			PlayerView.titel.setText(songs.get(PlayerView.lstSongs.getSelectedIndex()).getNaam()+" - "+ songs.get(PlayerView.lstSongs.getSelectedIndex()).getArtiest());

			//		PlayerView.artiest.setText(songs.get(PlayerView.lstSongs.getSelectedIndex()).getArtiest());
			//		PlayerView.album.setText(songs.get(PlayerView.lstSongs.getSelectedIndex()).getAlbum());
			//		PlayerView.jaar.setText(songs.get(PlayerView.lstSongs.getSelectedIndex()).getJaar()+ "");
			//		PlayerView.rating.setText(songs.get(PlayerView.lstSongs.getSelectedIndex()).getRating()+" sterren");


			System.err.println("playing: "+songs.get(PlayerView.lstSongs.getSelectedIndex()).getNaam()+"\n");
			
			final int length = (int) songs.get(PlayerView.lstSongs.getSelectedIndex()).getTijdsduur();
			PlayerView.sldTimeLine.setValue(0);

			int minutes = length/60; // number of minutes
			final int seconds = length%60; // number of seconds
			//
			String text = minutes+":"+seconds;

			Date date = new SimpleDateFormat("m:s").parse(text);
			String time = new SimpleDateFormat("mm:ss").format(date);
			PlayerView.tijdsduur.setText(time);

			int stepPS = ((int)length*1000) /100;

			timer.purge();
			PlayerView.sldTimeLine.setValue(0);
			timer = new Timer();
			timer.schedule(new Timeline(length), 0, stepPS);

			PlayerView.visual.start();
			startCountUpTimer();

			PlayerView.sldTimeLine.setValue(0);

		} catch (Exception e) {
		}
	}

	public void next(){
		stop();
		resetCountUpTimer();
		if(PlayerView.lstSongs.getModel().getSize() -1 == PlayerView.lstSongs.getSelectedIndex()){
			PlayerView.lstSongs.setSelectedIndex(0);
		}else{
			PlayerView.lstSongs.setSelectedIndex(PlayerView.lstSongs.getSelectedIndex() +1);
		}

		play = true;
		pause = false;

		View.PlayerView.btnPlay.setText("||");
		play();
	}

	public void songEnded(){
		if(PlayerView.sldTimeLine.getValue() == 100){
			resetCountUpTimer();
			next();
		}
	}

//	public void editTimeline(){
//		int perc = PlayerView.sldTimeLine.getValue();
//	}

	public void prev(){
		resetCountUpTimer();
		stop();
		if(PlayerView.lstSongs.getSelectedIndex() == 0){
			PlayerView.lstSongs.setSelectedIndex(PlayerView.lstSongs.getModel().getSize() -1);
		}else{
			PlayerView.lstSongs.setSelectedIndex(PlayerView.lstSongs.getSelectedIndex() -1);
		}

		play = true;
		pause = false;

		View.PlayerView.btnPlay.setText("||");
		play();
	}

	public void stopPressed(){
		play = false;
		View.PlayerView.btnPlay.setText(">");
		stop();
	}

	@SuppressWarnings("deprecation")
	public void stop(){

		try {
			t.stop();
			PlayerView.visual.stop();
			pauseCountUpTimer();
			resetCountUpTimer();
			pause = false;
			timer.cancel();
			PlayerView.sldTimeLine.setValue(0);

		} catch (Exception e) {
		}
	}

	public void updateListModel(){
		DBobject db = new DBobject();
		songs = db.loadDB();	

		for(int i = 0; i<songs.size() ; i++){
			model.add(i, songs.get(i).getNaam() + " - " + songs.get(i).getArtiest());
		}

		PlayerView.lstSongs.setModel(model);
		PlayerView.lstSongs.repaint();

		CurrentPlayList.getInstance().loadSongsToModel();
	}

	public void removeSong(){

//		if (PlayerView.lstSongs.getSelectedIndex()<=-1) {
//			JOptionPane.showMessageDialog(null, "Please select songs to remove.");
//		}else{

			Nummer s = songs.get(PlayerView.lstSongs.getSelectedIndex());

			System.out.println(PlayerView.lstSongs.getSelectedIndex());
			System.out.println(s.getNaam());

			DBobject db = new DBobject();
			db.removeSong(s);

			songs.remove(s);
			PlayerView.modelSongs.removeAllElements();
			updateListModel();
		}

//	}

	public void addToListModel(Nummer s){
		songs.add(s);
		model.add(PlayerView.lstSongs.getModel().getSize() , s.getNaam() + " - " + s.getArtiest());
		System.out.println("Shots been fired");

		PlayerView.lstSongs.setModel(model);
		PlayerView.lstSongs.repaint();
	}

	// begin count up timer
	private String myFormat(final long time) {
		final long hr = TimeUnit.MILLISECONDS.toHours(time);
		final long min = TimeUnit.MILLISECONDS.toMinutes(time
				- TimeUnit.HOURS.toMillis(hr));
		final long sec = TimeUnit.MILLISECONDS.toSeconds(time
				- TimeUnit.HOURS.toMillis(hr) - TimeUnit.MINUTES.toMillis(min));
		return String.format("%02d:%02d", min, sec);
	}

	private String getCurrentTime(long time) {
		return myFormat(time);
	}

	public void actionPerformed(ActionEvent ae) {
		PlayerView.secondstimer.setText(getCurrentTime(System.currentTimeMillis() - startTime));
	}

	public void startCountUpTimer() {
		if (isRunning == false) {
			startTime = System.currentTimeMillis();
		} else {
			startTime = System.currentTimeMillis() - (pauseTime - startTime);
		}

		isRunning = true;
		secondstimer.start();
	}

	public void pauseCountUpTimer() {           
		pauseTime = System.currentTimeMillis();
		secondstimer.stop();
	}

	public void resetCountUpTimer() {       
		startTime = 0;
		isRunning = false;
		PlayerView.secondstimer.setText(getCurrentTime(System.currentTimeMillis() - System.currentTimeMillis()));
	}

	// eind count up timer

	public void setVolume(){

		if(PlayerView.setVolume.getFloatValue() != 0.1f){
			Volume.setVolume(PlayerView.setVolume.getFloatValue());
		}else{
			Volume.setVolume(0.0f);
		}

		//	 System.out.println("user got: " +PlayerView.setVolume.getFloatValue() + " ival: " + PlayerView.setVolume.getValue());
	}

}
